Broadcast使用场景解读

BroadcastReceiver组件

在之前的一篇文章《基于场景解读Android四大组件》谈到BroadcastReceiver是Android提供给开发者的一个组件,主要用来完成前台和后台之前的通信,也就是Activity和Service之间的通信。今天我们继续通过使用场景来分析Android中的Broadcaster和BroadcastReceiver。

我们知道Android的底层使用了Linux内核,Linux下面提供了很多的IPC通信方式,比如消息,管道,共享内存,信号量,Socket等等。但是Android并没有采用Linux的几种IPC方案,而是使用了binder来完成进程之间的IPC。这主要是基于以下两点考虑:

  • 效率,其底层使用了共享内存机制,提高了数据读写的效率
  • 安全,从底层着手控制每个进程之间的访问权限,相比Linux在上层来控制访问权限要更加安全
那么binder又是如何在Android中使用的呢?主要有两种方式:
  • 采用代理模式,每个Client在访问Service之前都会获取一个Service的代理,然后通过这个代理来调用Service端提供的功能。比方说我们在Activity或者Service中通过getSystemService()获取到的XXXManager接口就属于这种。
  • 采用广播发送/接收的形式,也就是我们今天要讲的Broadcast和BroadcastReceiver,这种方式本质上属于消息订阅/发布的事件驱动流形式。
那么这两种形式有什么区别呢?
  • 代理模式一般用于点对点通信,也就是网络通信中的单播模式,优点是效率高,缺点是通信是即时发起的,同步调用。
  • 广播方式的话,效率相对低一些,但是通信是随时发起,异步调用。

这里引用老罗一篇博客《Android系统中的广播(Broadcast)机制》里面的描述会更清晰:

在Android系统中,为什么需要广播机制呢?广播机制,本质上它就是一种组件间的通信方式,如果是两个组件位于不同的进程当中,那么可以用Binder机制来实现,如果两个组件是在同一个进程中,那么它们之间可以用来通信的方式就更多了,这样看来,广播机制似乎是多余的。然而,广播机制却是不可替代的,它和Binder机制不一样的地方在于,广播的发送者和接收者事先是不需要知道对方的存在的,这样带来的好处便是,系统的各个组件可以松耦合地组织在一起,这样系统就具有高度的可扩展性,容易与其它系统进行集成。
在软件工程中,是非常强调模块之间的高内聚低耦合性的,不然的话,随着系统越来越庞大,就会面临着越来越难维护的风险,最后导致整个项目的失败。Android应用程序的组织方式,可以说是把这种高内聚低耦合性的思想贯彻得非常透彻,在任何一个Activity中,都可以使用一个简单的Intent,通过startActivity或者startService,就可以把另外一个Activity或者Service启动起来为它服务,而且它根本上不依赖这个Activity或者Service的实现,只需要知道它的字符串形式的名字即可,而广播机制更绝,它连接收者的名字都不需要知道。

关于Android Broadcast的使用这里不做介绍,我们这里只谈谈Broadcast的使用场景。目前在App开发中的消息全局通知方案有以下几种:系统广播,观察者和eventbus等第三方开源工具。观察者和eventbus都只能用于应用内的消息通信,他们之间的区别主要在于实现方式的不同。观察者是由用户通过handler自己实现一套,维护和扩展方便,但是一般不支持优先级和sticky等原生广播特性,而且随着业务逻辑复杂度增加,监听接口会迅速膨胀。eventbus等第三方开源工具功能使用简单,功能也要强大一些,支持优先级和sticky等原生广播特性。但是由于是使用第三方库所以在不了解其实现原理的情况下bug调试跟踪会变得困难,而且更新库(接口或者一些属性有变动的话)可能会影响到代码的大面积改动。broadcast不仅支持应用内通信也支持不同应用进程之间的通信。但是由于其底层使用binder来实现,所以效率上与前两者相比要低一些。当然broadcast最大的优势还是在对系统事件的监听上,这是其他两个方案没法办到的。所以关于消息通信方案的选择上,需要根据自己的需求来选择合适的方案。当需要App应用内通信时,优先选择观察者或者Eventbus,当需要进程间通信或者监听系统广播事件时,选择Broadcast。另外再提一下LocalBroadcastManager这个类,它是一个本地广播管理器,估计是Android考虑到原生Broadcast的效率问题而提供的一个轻量级的广播。它主要是解决App应用内通信的问题,采用handler实现,跟观察者的实现方案类似,有兴趣的可以去看下它的源码。

Android提供了BroadcastReceiver这个组件来帮助我们监听广播消息,这里我们来看下BroadcastReceiver的使用场景:
  • App全局监听,这种主要用于在AndroidManifest中静态注册的广播接收器,一般我们在收到该消息后,需要做一些相应的动作,而这些动作与当前App的组件,比如Activity或者Service的是否运行无关,比如我们在集成第三方Push SDK时,一般都会添加一个静态注册的BroadcastReceiver来监听Push消息,当有Push消息过来时,会在后台做一些网络请求或者发送通知等等。
  • 组件局部监听,这种主要是在Activity或者Service中使用registerReceiver()动态注册的广播接收器,因为当我们收到一些特定的消息,比如网络连接发生变化时,我们可能需要在当前Activity页面给用户一些UI上的提示,或者将Service中的网络请求任务暂停。所以这种动态注册的广播接收器适合特定组件的特定消息处理。
关于BroadcastReceiver使用需要注意的几点:
  • onReceive中不能执行耗时操作,如果耗时超过10s会弹出ANR。
  • onReceive中context参数,如果是静态注册的广播,context为ReceiverRestrictedContext,所在如果在这里要启动一个Activity的话(调用startActivity),需要在intent中添加Intent.FLAG_ACTIVITY_NEW_TASK;如果是动态注册的广播,context为当前注册时所在的组件,比如Activity或者Service。
  • 监听系统广播,需要在AndroidManifest中申请权限,此外,Android高版本系统对于一些重要的系统广播,比如开机启动,网络连接,电量变化,锁屏等做了限制,如果需要监听这些广播,需要做系统兼容性处理。
  • 普通广播的广播接收器是并行无序执行的,有序广播的广播接收器按照广播优先级串行执行
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容